function parityPerceptron = parityPerceptron(N,b=0.5,e=0.5, epocas=50)
alpha=0.9;
cantAciertos=0;
TANH=1;
EXP=2;
LINEAL=3;
FUNC=TANH;

N=[1 N 1];					

for c=1:length(N)-1
	w{c} = (rand(N(c+1),N(c)+1)-0.5); %el +1 es por el umbral.
	delta_anterior{c}=zeros(N(c+1),N(c)+1);
	w{c} = w{c} ./ 100;
endfor

psi=[(25:0.05:45)']; %uniforme
%psi=[(40:0.01:45)']; %uniforme
%psi=[(0:0.05:4)']; %unifore
%psi=[(15:0.3:19)';(19:0.1:21)';(21:0.3:28)';(28:0.1:30)';(30:0.3:35)';(35:0.1:45)'];  %personalizado
%psi=[(0*pi:0.01:1*pi)'];

%Para las salidas se aplica directamente la funcion al vector (funcion nro 9)
s=f(psi); 		

%Actualmente esta funcion devuelve psi completo, mas adelante hay que elegir un subconjunto
psiTraining=getPsiTraining(psi);	
sTraining=f(psiTraining);		

errorAnt=0;
for i=1:rows(psiTraining)	
	patron=v{1}=horzcat(psiTraining(i,:),-1); %seteo el inicixal
	for k=2:length(N)-1
		v{k} = applyG(b, (w{k-1}*v{k-1}')', FUNC);
		v{k} = horzcat(v{k},-1);
	endfor
	salida = applyG(b,(w{k}*v{k}')', LINEAL); %';
	errorpatronfin=(sTraining(i)-salida)^2;
	errorAnt=errorAnt+errorpatronfin;
endfor
errorAnt=errorAnt/2

j=0;
do
  indices = randperm(rows(psiTraining));
  erroracum=0;
  wold=w;
  for ind=1:rows(psiTraining)
	i=indices(ind);
	h=[];
	v=[];
	v{1}=horzcat(psiTraining(i,:),-1); %seteo el inicixal
	
	for k=2:length(N)-1
		h{k} = (w{k-1}*v{k-1}')';
		v{k} = applyG(b, h{k}, FUNC);			
		v{k} = horzcat(v{k},-1);
	endfor

	h{k+1} = (w{k}*v{k}')';
	v{k+1} = applyG(b,h{k+1}, LINEAL);

	delta{k} = (sTraining(i)-v{k+1})*(applyGprima(b, h{k+1}, LINEAL)+0.1);		
		
	for p=k-1:-1:1
		waux = sacarUmbral(w{p+1});
		delta{p}=(applyGprima(b,h{p+1},FUNC)+0.1).*(delta{p+1}*waux);
	endfor

	for p=1:k
		dw=(e*delta{p}(:,:)'*v{p}) + alpha*delta_anterior{p};
		delta_anterior{p}=dw;
		w{p}=w{p}.+dw;
	endfor
	erroractual=(sTraining(i)-v{k+1})^2;

	
	if (isnan(erroractual))
		j
		ind
		printf("SE FUE A NAN\n\n");
		return
	endif
	erroracum+=erroractual;
  endfor
  erroracum=erroracum/2;

  if (erroracum<errorAnt)
	errorAnt=erroracum;  
	cantAciertos=cantAciertos+1;
	if (cantAciertos>=1)
		e=e+0.01;
		cantAciertos=0;
	endif
  endif
  if (erroracum>errorAnt)
	w=wold;
	erroracum=errorAnt;  
	cantAciertos=0;
	e=e-(0.1*e);
  endif

  erroracum
  fflush(1);
  if (mod(j,10)==0)
	j 
	%erroracum
	e
	plot(psiTraining(:,1)',sTraining,"3;esperada;", psiTraining(:,1)',aplicarRed(psiTraining,w,N,b), "1;out;")
	drawnow
	fflush(1);
  endif
  
  j++;
until(j==epocas || erroracum<=10e-3);
j
erroracum

salidafinal=aplicarRed(psiTraining,w,N,b);
plot(psiTraining(:,1)',sTraining,"3;esperada;", psiTraining(:,1)',salidafinal, "1;out;"); %ploteo la funcion original y la salida para ver si aprendio la red

endfunction